<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>贪吃蛇-极简版</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        ul {
            list-style: none;
        }

        .container {
            width: 1000px;
            height: 800px;
            margin: 10px auto;
            background-color: antiquewhite;
            position: relative;
        }

        .food {
            width: 20px;
            height: 20px;
            background-color: lightcoral;
            position: absolute;
        }

        .snake_body .cube {
            position: absolute;
            width: 20px;
            height: 20px;
            background-color: #bff;
        }

        .cube.head {
            background-color: rgb(4, 147, 250);
        }

        .game-over {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            font-size: 24px;
            color: red;
            font-weight: bold;
        }

        .restart-button {
            position: absolute;
            top: 60%;
            left: 50%;
            transform: translate(-50%, -50%);
            padding: 10px 20px;
            font-size: 18px;
            cursor: pointer;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 5px;
        }
    </style>
</head>
<body>
    <div class="container">
        <ul class="snake_body">
            <!-- <li class="cube"></li>
            <li class="cube"></li>
            <li class="cube head"></li> -->
        </ul>
    </div>
    <div class="game-over" id="game-over" style="display: none;">游戏结束！</div>
    <button class="restart-button" id="restart-button" style="display: none;">重新开始</button>

    <script>
        const container = document.querySelector('.container');
        const ul_body = document.querySelector('.snake_body');
        const gameOverDiv = document.getElementById('game-over');
        const restartButton = document.getElementById('restart-button');

        let snake_arr = [
            { id: 0, left: 100, top: 100, move_direction: 'r' },
            { id: 1, left: 80, top: 100 },
            { id: 2, left: 60, top: 100 }
        ];

        render_snake();

        function render_snake(flag = false) {
            if (flag) {
                ul_body.innerHTML = '';
            }

            for (let i = snake_arr.length - 1; i >= 0; i--) {
                let li = document.createElement('li');
                if (snake_arr[i].id == 0) {
                    li.classList.add('cube', 'head');
                } else {
                    li.classList.add('cube');
                }
                li.style.left = snake_arr[i].left + 'px';
                li.style.top = snake_arr[i].top + 'px';
                ul_body.append(li);
            }
        }

        function add_body(n = 1) {
            for (let i = 0; i < n; i++) {
                let length = snake_arr.length;
                snake_arr.push({ id: length, left: snake_arr[length - 1].left, top: snake_arr[length - 1].top });
            }
            render_snake(true);
        }

        function snake_move() {
            let d = snake_arr[0].move_direction;

            for (let i = snake_arr.length - 1; i >= 1; i--) {
                snake_arr[i].left = snake_arr[i - 1].left;
                snake_arr[i].top = snake_arr[i - 1].top;
            }

            switch (d) {
                case 'l':
                    snake_arr[0].left -= 20;
                    break;
                case 'r':
                    snake_arr[0].left += 20;
                    break;
                case 'u':
                    snake_arr[0].top -= 20;
                    break;
                case 'd':
                    snake_arr[0].top += 20;
                    break;
            }

            render_snake(true);
        }

        let auto_move = setInterval(snake_move, 100);

        let lock = false;
        function test_key(key) {
            if (!lock) {
                lock = true;
                let d = snake_arr[0].move_direction;
                let key_type = 'vertical';
                if (key == 'ArrowLeft' || key == 'ArrowRight') {
                    key_type = 'level';
                } else {
                    key_type = 'vertical';
                }

                if (key_type == 'level' && (d == 'r' || d == 'l')) {
                } else if (key_type == 'vertical' && (d == 'u' || d == 'd')) {
                } else {
                    key_change_direction(key);
                }
                setTimeout(() => {
                    lock = false;
                }, 50);
            }
        }

        function key_change_direction(key) {
            switch (key) {
                case 'ArrowLeft':
                    snake_arr[0].move_direction = 'l';
                    break;
                case 'ArrowRight':
                    snake_arr[0].move_direction = 'r';
                    break;
                case 'ArrowUp':
                    snake_arr[0].move_direction = 'u';
                    break;
                case 'ArrowDown':
                    snake_arr[0].move_direction = 'd';
                    break;
                default:
                    console.log(key);
            }
        }

        window.addEventListener('keyup', (e) => {
            test_key(e.key);
        });

        function random_food() {
            let random_left = Math.floor(Math.random() * container.clientWidth / 20);
            let random_top = Math.floor(Math.random() * container.clientHeight / 20);

            let food = document.createElement('div');
            food.classList.add('food');
            food.style.left = random_left * 20 + 'px';
            food.style.top = random_top * 20 + 'px';
            container.append(food);
        }

        random_food();

        function eat_food() {
            let test_head_position;
            let food = document.querySelector('.food');
            let [fl, ft] = [food.offsetLeft, food.offsetTop];

            test_head_position = setInterval(() => {
                let head = document.querySelector('.snake_body .head');
                let [hl, ht] = [head.offsetLeft, head.offsetTop];

                if (hl == fl && ht == ft) {
                    clearInterval(test_head_position);
                    food.parentElement.removeChild(food);
                    random_food();
                    eat_food();
                    add_body(1);
                }
            }, 100);
        }

        eat_food();

        let container_w = container.offsetWidth;
        let container_h = container.offsetHeight;

        let test_failue = setInterval(() => {
            if (snake_arr[0].left >= container_w || snake_arr[0].left < 0 || snake_arr[0].top >= container_h || snake_arr[0].top < 0) {
                gameOver();
            } else if (test_body()) {
                gameOver();
            }
        }, 100);

        function test_body() {
            for (let i = snake_arr.length - 1; i > 0; i--) {
                if (snake_arr[0].left == snake_arr[i].left && snake_arr[0].top == snake_arr[i].top) {
                    return true;
                }
            }
            return false;
        }

        function gameOver() {
            clearInterval(test_failue);
            clearInterval(auto_move);
            gameOverDiv.style.display = 'block';
            restartButton.style.display = 'block';
        }

        restartButton.addEventListener('click', () => {
            location.reload();
        });
    </script>
</body>
</html>
